package com.cynen.p42u.util;

import com.cynen.p42u.pojo.JavLibInfo;
import com.cynen.p42u.service.JavLibService;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;

@Component
public class HttpUtils {

    /**
     * 指定存储的路径.
     */
    @Value("${pic.save.path}")
    private String desPath;
    // 创建连接池管理器
    private  PoolingHttpClientConnectionManager cm;

    // 构造方法:
    public HttpUtils(){
        this.cm = new  PoolingHttpClientConnectionManager();
        // ----配置链接池.
        //1. 设置最大连接数.
        cm.setMaxTotal(100);
        // 2.设置主机分配最大连接数
        cm.setDefaultMaxPerRoute(10); // 给指定主机最大分配10个链接,为了应对多主机爬虫.
    }

    /**
     * 根据请求地址,下载页面数据
     * @param url
     * @return 页面数据
     */
    public String doGetHtml(String url){
        // 使用连接池,获取链接对象.而不是手工创建.
        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(this.cm).build();
        HttpGet httpGet = new HttpGet(url);
        httpGet.setConfig(this.setConfig());
        // 模拟浏览器浏览（user-agent的值可以通过浏览器浏览，查看发出请求的头文件获取）
        httpGet.setHeader("user-agent", "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36");
        CloseableHttpResponse httpResponse = null;
        try {
            // 解析响应数据.
            httpResponse = httpClient.execute(httpGet);
            if (httpResponse.getStatusLine().getStatusCode() == 200){
                String content = EntityUtils.toString(httpResponse.getEntity(),"utf8");
                return content;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 关闭资源.
            try {
                httpResponse.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 千万不能关闭httpclient.其是连接池中的对象.
            // httpClient.close();
        }
        return "";
    }


    @Autowired
    private JavLibService javLibService;
    /**
     * 下载图片.
     * @param javLibInfo
     * @return 图片名称
     */
    public void doGetImage(JavLibInfo javLibInfo){
        // 使用连接池,获取链接对象.而不是手工创建.
        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(this.cm).build();
        HttpGet httpGet = new HttpGet("http:"+javLibInfo.getPicUrl());
        httpGet.setConfig(this.setConfig());
        // 模拟浏览器浏览（user-agent的值可以通过浏览器浏览，查看发出请求的头文件获取）
        httpGet.setHeader("user-agent", "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36");
        // httpGet.setHeader("Cookie","app_uid=ygb3KF5JBcuvlnYR4ZNlAg=="); // 不用配置,否则易报错.
        CloseableHttpResponse httpResponse = null;
        OutputStream opt = null;
        try {
            // 解析响应数据.
            httpResponse = httpClient.execute(httpGet);
            if (httpResponse.getStatusLine().getStatusCode() == 200){
               // 下载图片.
                // 1.获取图片后缀
                // //pics.dmm.co.jp/mono/movie/adult/h_1359omt015/h_1359omt015pl.jpg
                String url = javLibInfo.getPicUrl();
                String extName = url.substring(url.lastIndexOf("."));
                // 2.重命名
                String picName = javLibInfo.getVideoId() + extName;
                //3.下载图片
                opt = new FileOutputStream(new File(desPath +"/"+ picName));
                System.out.println("图片路径:"+desPath + picName);
                httpResponse.getEntity().writeTo(opt);
                opt.flush();
                // 下载完成的,更新完成标志.
                javLibInfo.setDownloads(javLibInfo.getDownloads()+1);
                javLibService.update(javLibInfo);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 关闭资源.
            try {
                opt.close();
                httpResponse.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 千万不能关闭httpclient.其是连接池中的对象.
            // httpClient.close();
        }
    }


    private RequestConfig setConfig() {
        // 配置请求信息
        RequestConfig config = RequestConfig.custom().setConnectTimeout(2000) //创建链接的最长是时间,单位毫秒.
                .setConnectionRequestTimeout(1000) // 设置获取链接的最长时间,单位毫秒
                .setSocketTimeout(20*1000) // 设置Socket传输数据的最长时间,单位毫秒.
                .build();
        return config;
    }
}
